package com.cygsunri.consumption.task;

import com.cygsunri.consumption.entity.Branch;
import com.cygsunri.consumption.entity.Building;
import com.cygsunri.consumption.entity.enumerate.EnergySort;
import com.cygsunri.consumption.service.BranchService;
import com.cygsunri.consumption.service.BuildingService;
import com.cygsunri.history.service.GeneralDataService;
import com.cygsunri.measurement.calculate.AbstractComplexEndureCalculateService;
import com.cygsunri.measurement.entity.MeasurementValue;
import com.cygsunri.scada.base.BasePSR;
import com.cygsunri.scada.service.ScadaMeasurementService;
import com.cygsunri.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 计算建筑各种能耗合计
 */
@Component
@Slf4j
@ConditionalOnProperty(prefix = "task.consumption.building", name = "open", havingValue = "true")
@PropertySource(name = "application.yml", value = {"classpath:application.yml"}, ignoreResourceNotFound = false, encoding = "UTF-8")
public class BuildingCalcTask extends AbstractComplexEndureCalculateService {

    @Autowired
    private BuildingService buildingService;

    @Autowired
    private BranchService branchService;

    @Autowired
    private ScadaMeasurementService scadaMeasurementService;

    @Autowired
    private GeneralDataService generalDataService;

    private Map<Building, List<EnergySort>> map = new HashMap<>();

    @Bean
    public void buildingCalcInit(){
        List<Building> buildings = buildingService.getAllBuilding();
        for (Building building : buildings) {
            map.put(building, buildingService.getBuildingEnergySort(building.getId()));
        }
    }

    /*fixedRate:上一次开始执行时间点之后5秒再执行*/
    /*@Scheduled(fixedRate = 5000)*/
    @Scheduled(cron = "${task.consumption.building.cron}")
    private void buildingCalc() {
        long a = System.currentTimeMillis();

        map.forEach((building, energySorts) ->
                energySorts.forEach(energySort ->
                        buildingEnergySortCalc(building, energySort)
                )
        );

        log.info("建筑计算量共耗时：{} ms", System.currentTimeMillis() - a);
    }

    /**
     * 计算建筑合计能耗
     */
    private void buildingEnergySortCalc(Building building, EnergySort energySort) {
        //energySort.getName()作为计算量dataName
        if (!this.getNeedEndureCalculate(building.getPsrID(), building.getName(), energySort.getName())) {
            return;
        }
        ImmutablePair<String, Integer> pair = scadaMeasurementService.getMeasurementID(building.getPsrID(), energySort.getName());
        if (pair == null) {
            return;
        }
        Double sum = 0d;
        int num = 0;
        List<Branch> branches = branchService.getBranchesByBuildingAndEnergySort(building.getId(), energySort.getName());
        for (Branch branch : branches) {
            BasePSR basePSR = new BasePSR().setId(branch.getPsrID());
            MeasurementValue m = new MeasurementValue().setO(basePSR).setName(energySort.getName()).setRdb(true);
            m = generalDataService.getValue(m);
            if (!m.isInValid() && m.getData() != null) {
                sum += m.getData();
                num ++;
            }
        }
        if (num > 0) {
            this.saveMean(pair.getLeft(), sum, DateUtil.nowMilliSeconds(), MeasurementValue.Quality.Calc.getKey());

        }
    }
}
